/**
 *  ClassName: FacesUtil.java
 *  created on Jan 13, 2008
 *  Copyrights 2007-2008 qjyong All rights reserved.
 *  EMail: qjyong@gmail.com
 */
package com.yunhoo.sys.util.common;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sun.faces.util.MessageFactory;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.el.ValueBinding;

/**
 * JSF的Servlet相关工具类
 * 
 * @author qiujy
 * @version 1.0
 * 
 */
public class FacesUtils {

    /**
     * 获取servletContext实例
     *
     * @return the servlet context
     */
    public static ServletContext getServletContext() {
        return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    }

    /**
     * 按指定名把指定的ManagedBean保存到Session中
     *
     * @param beanName
     * @param managedBean
     */
    public static void setManagedBeanInSession(String beanName,
            Object managedBean) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(beanName, managedBean);
    }

    /**
     * 根据请求的参数名得到值
     *
     * @param name
     *            参数的名
     * @return 参数的值
     */
    public static String getRequestParameter(String name) {
        return (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
    }

    /**
     * 把指定的提示消息key对应的消息添加到FacesContext中
     *
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     */
    public static void addInfoMessage(String messageId) {
        addInfoMessage(null, messageId);
    }

    /**
     * 把指定的clientId组件的指定的提示消息key对应的消息添加到FacesContext中
     *
     * @param clientId
     *            组件的clientId
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     */
    public static void addInfoMessage(String clientId, String messageId) {
        FacesMessage msg = MessageFactory.getMessage(messageId);
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(clientId, msg);
    }

    /**
     * 把指定的clientId组件的指定的提示消息key对应的消息格式化添加到FacesContext中
     *
     * @param clientId
     *            组件的clientId
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     * @param params
     *            可变长参数
     */
    public static void addInfoMessage(String clientId, String messageId,
            Object... params) {
        FacesMessage msg = MessageFactory.getMessage(messageId, params);
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(clientId, msg);
    }

    /**
     * 把指定的错误消息key对应的消息添加到FacesContext中
     *
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     */
    public static void addErrorMessage(String messageId) {
        addErrorMessage(null, messageId);
    }

    /**
     * 把指定clientId的组件的指定的错误消息key对应的消息添加到FacesContext中
     *
     * @param clientId
     *            组件的clientId
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     */
    public static void addErrorMessage(String clientId, String messageId) {
        FacesMessage msg = MessageFactory.getMessage(messageId);
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext.getCurrentInstance().addMessage(clientId, msg);
    }

    /**
     * 把指定clientId的组件的指定的错误消息key对应的消息格式化再添加到FacesContext中
     *
     * @param clientId
     *            组件的clientId
     * @param messageId
     *            错误消息key(消息资源文件中要存在)
     * @param params
     *            可变长参数
     */
    public static void addErrorMessage(String clientId, String messageId,
            Object... params) {
        FacesMessage msg = MessageFactory.getMessage(messageId, params);
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext.getCurrentInstance().addMessage(clientId, msg);
    }

    /**
     * 把指定的属性"name-value"对存放到请求中
     *
     * @param name
     *            属性名
     * @param value
     *            属性值
     */
    public static void setRequestAttribute(String name, Object value) {
        getServletRequest().setAttribute(name, value);
    }

    /**
     * 根据指定的属性名从会话对象中取得属性值
     *
     * @param name
     *            属性的名
     * @return 属性的值
     */
    public static Object getSessionAttribute(String name) {
        return getSession().getAttribute(name);
    }

    /**
     * 把指定的属性"name-value"对存放到会话中
     *
     * @param name
     *            属性名
     * @param value
     *            属性值
     */
    public static void setSessionAttribute(String name, Object value) {
        getSession().setAttribute(name, value);
    }

    /**
     * 根据指定的属性名从会话对象中移除对应的属性值
     *
     * @param 指定的名字
     */
    public static void removeSessionAttribute(String name) {
        getSession().removeAttribute(name);
    }

    /**
     * 获得HttpSession实例
     *
     * @return
     */
    public static HttpSession getSession() {
        return getServletRequest().getSession();
    }

    /**
     * 获得HttpSession实例
     *
     * @param flag
     * @return
     */
    public static HttpSession getSession(boolean flag) {
        return getServletRequest().getSession(flag);
    }

    /**
     * 得到Http响应对象
     *
     * @return HttpServletResponse实例
     */
    public static HttpServletResponse getServletResponse() {
        return (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    }

    /**
     * 根据托管Bean的名字从FacesContext中获得对应托管Bean的实例
     *
     * @param beanName
     *            托管Bean的名
     * @return 托管Bean实例
     */
    public static Object getManagedBean(String beanName) {

        FacesContext ctx = FacesContext.getCurrentInstance();
        // JSF1.1
        // return
        // ctx.getApplication().getVariableResolver().resolveVariable(ctx,"bean_name");
        return ctx.getApplication().getELResolver().getValue(
                ctx.getELContext(), null, beanName);

    }

    /**
     * 获得HttpServletRequest实例
     *
     * @return HttpServletRequest实例
     */
    public static HttpServletRequest getServletRequest() {
        return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    }

    private static Application getApplication() {
        ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
        return appFactory.getApplication();
    }
}
